package com.qf.commons.redis.bloom;

import com.qf.commons.core.utils.ApplicationUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;

/**
 * description: 操作bloom过滤器
 * author: Ken
 * 公众号：Java架构栈
 */
public class CBloom {

    private static StringRedisTemplate redisTemplate;

    static {
        redisTemplate = ApplicationUtils.getBean(StringRedisTemplate.class);
    }

    //初始化bloom过滤器的lua脚本
    private static String initLua = "local key = KEYS[1]\n" +
            "local err = ARGV[1]\n" +
            "local len = ARGV[2]\n" +
            "local flag = redis.call('exists', key)\n" +
            "if flag == 0 then\n" +
            "   redis.call('bf.reserve', key, err, len)\n" +
            "   return 1\n" +
            "end\n" +
            "return 0";

    //添加元素的lua脚本
    private static String addLua = "local key = KEYS[1]\n" +
            "local value = ARGV[1]\n" +
            "return redis.call('bf.add', key, value)";

    //判断元素是否存在
    private static String existsLua = "local key = KEYS[1]\n" +
            "local value = ARGV[1]\n" +
            "return redis.call('bf.exists', key, value)";

    /**
     * 初始化bloom过滤器
     */
    public static boolean init(String key, double err, long len){
        Long result = redisTemplate.execute(new DefaultRedisScript<>(initLua, Long.class),
                Collections.singletonList(key),
                err + "", len + "");
        return result == 1;
    }

    /**
     * 添加到bloom过滤器
     * @return
     */
    public static boolean add(String key, String value){
        Long result = redisTemplate.execute(new DefaultRedisScript<>(addLua, Long.class),
                Collections.singletonList(key),
                value);
        return result == 1;
    }

    /**
     * 判断是否存在
     * @return
     */
    public static boolean exists(String key, String value){
        Long result = redisTemplate.execute(new DefaultRedisScript<>(existsLua, Long.class),
                Collections.singletonList(key),
                value);
        return result == 1;
    }
}
